﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Diagnostics;
using System.IO;

namespace Prism.Core.Net.Tcp
{
    internal class SpeedLimitableNetworkHealper : ProgressableNetworkHelper
    {
        public SpeedLimitableNetworkHealper(TcpClient TcpClient)
            : base(TcpClient)
        {
        }

        protected override void OnStartWriteDataProgress(object state)
        {
            // 要写入的数据。
            var buffer = state as byte[];
            System.Diagnostics.Debug.Print("要发送的数据的长度：" + buffer.Length.ToString());
            // 要写入的数据的长度。
            var length = buffer.Length;
            // 将长度信息转换为Bytes。
            var lengthHead = BitConverter.GetBytes(length);
            System.Diagnostics.Debug.Print("计算获得的数据的长度：" + length.ToString());
            Debug.Print(buffer.Last().ToString());

            // 发送长度头信息。
            try
            {
                this.NetworkStream.Write(lengthHead, 0, lengthHead.Length);
            }
            catch (IOException ex)
            {
                this.OnWriteDataProgress(new DataProgressEventArgs() { Progress = 0d, IsCompleted = false });
                this.EndWriteCurrent(false, ex);
                return;
            }

            // 获取缓冲总长度。
            this.WriteSpeedTracker.TotalLength = length;

            // 分块操作。
            var offset = 0;

            //开始写数据。
            while (true)
            {
                try
                {
                    if (length - offset >= this.blockSize)
                    {
                        this.NetworkStream.Write(buffer, offset, this.blockSize);
                        offset += this.blockSize;
                        this.WriteSpeedTracker.NowLength = offset;
                    }
                    else if (length - offset < this.blockSize && length != offset)
                    {
                        this.NetworkStream.Write(buffer, offset, length - offset);
                        offset = length;
                        this.WriteSpeedTracker.NowLength = offset;
                    }
                    else break;
                }
                catch (IOException ex)
                {
                    this.OnWriteDataProgress(new DataProgressEventArgs() { Progress = 0d, IsCompleted = false });
                    this.EndWriteCurrent(false, ex);
                    return;
                }
                if (offset % 1024 == 0)
                {
                    var progress = 100 * offset / length;
                    this.OnWriteDataProgress(new DataProgressEventArgs() { Progress = progress, IsCompleted = false });
                }
            }

            this.OnWriteDataProgress(new DataProgressEventArgs() { Progress = 100d, IsCompleted = true });

            // 结束写入。
            this.WriteSpeedTracker = new DataTransportSpeedTracker();
            this.EndWriteCurrent(true, null);
        }

        protected override void OnStartReadDataProgress()
        {
            // 初始化长度缓冲。
            var lengthHead = new byte[4];
            try
            {
                this.NetworkStream.Read(lengthHead, 0, lengthHead.Length);
            }
            catch (IOException ex)
            {
                this.EndReadCurrent(null, ex);
                return;
            }
            catch (ObjectDisposedException ex)
            {
                this.EndReadCurrent(null, ex);
                return;
            }

            // 获取长度值。
            var length = BitConverter.ToInt32(lengthHead, 0);
            // 缓冲。
            var buffer = new byte[length];
            // 获取总长度。
            this.ReadSpeedTracker.TotalLength = length;

            // 分块操作。
            var offset = 0;

            // 开始读取数据。
            while (true)
            {
                try
                {
                    if (length - offset >= this.blockSize)
                    {
                        this.NetworkStream.Read(buffer, offset, this.blockSize);
                        offset += this.blockSize;
                        this.ReadSpeedTracker.NowLength = offset;
                    }
                    else if (length - offset < this.blockSize && length != offset)
                    {
                        this.NetworkStream.Read(buffer, offset, length - offset);
                        offset = length;
                        this.ReadSpeedTracker.NowLength = offset;
                    }
                    else break;
                }
                catch (IOException ex)
                {
                    this.OnReadDataProgress(new DataProgressEventArgs() { IsCompleted = false, Progress = 0d });
                    this.EndReadCurrent(null, ex);
                    return;
                }

                if (offset % 1024 == 0)
                {
                    var progress = 100 * offset / length;
                    this.OnReadDataProgress(new DataProgressEventArgs() { IsCompleted = false, Progress = progress });
                }
            }
            // 获取最终值。
            System.Diagnostics.Debug.Print("接收到的头部长度信息：" + length.ToString());
            System.Diagnostics.Debug.Print("实际接收到的数据长度：" + buffer.Length.ToString());
            Debug.Print(buffer.Last().ToString());

            this.OnReadDataProgress(new DataProgressEventArgs() { IsCompleted = true, Progress = 100d });


            // 结束读取。
            this.ReadSpeedTracker = new DataTransportSpeedTracker();
            this.EndReadCurrent(this.OnDeserializeData(buffer), null);
        }

        protected override void WriteCurrent()
        {
            base.WriteCurrent();
        }

        protected override void ReadCurrent()
        {
            base.ReadCurrent();
        }

        public DataTransportSpeedLimiter ReadDataSpeedLimiter { get; set; }

        public DataTransportSpeedLimiter WriteDataSpeedLimiter { get; set; }
    }
}
